# coding=utf-8
import json
import os
import smtplib
import sys

import sendemail.email_util as util

from sendemail.emailconfig import host
from sendemail.emailconfig import port
from sendemail.emailconfig import sender
from sendemail.emailconfig import auth_code
from sendemail.emailconfig import receivers_str
from sendemail.emailconfig import cc_receivers_str
from sendemail.emailconfig import bcc_receivers_str
from sendemail.emailconfig import separate_delivery

# 校验输入参数
try:
    receivers = json.loads(receivers_str)
    cc_receivers = json.loads(cc_receivers_str)
    bcc_receivers = json.loads(bcc_receivers_str)
except Exception as e:
    print('error: 收件人、抄送人或密送人格式错误，格式为：\'["aaa@qq.com", "bbb@163.com"]\'')
    sys.exit(1)
# if subject.isspace():
#     print('error: subject不能为空')
# if not text or text.isspace():
#     print('error: text不能为空')
# msg_types = ['plain', 'html']
# if msg_type not in msg_types:
#     print('error: type类型定义错误，请输入 plain/html')
#     sys.exit(1)
separate_delivery = True if separate_delivery == 'true' else False
# if attach_path and not attach_path.isspace():
#     if attach_path.endswith('/'):
#         attach_path = attach_path[:-1]
#     if not os.path.exists(attach_path):
#         print('error: 附件不存在，请检查attach_path')
#         sys.exit(1)

# 日志
print('发件人：', sender)
if len(receivers) != 0:
    print('收件人：', ', '.join(receivers))
if len(cc_receivers) != 0:
    print('抄送人：', ', '.join(cc_receivers))
if len(bcc_receivers) != 0:
    print('密送人：', ', '.join(bcc_receivers))
# print('标题：', subject)
# if attach_path and not attach_path.isspace():
#     file_name = os.path.basename(attach_path)
#     print('文件名：', file_name if os.path.isfile(attach_path) else file_name + '.zip')


def connection():
    print('host：', host)
    print('port：', port)
    try:
        if port == '465':
            server = smtplib.SMTP_SSL(host, port)
        else:
            server = smtplib.SMTP(host, port)
        server.timeout = 5
        server.login(sender, auth_code)
        return server
    except Exception as e:
        print('error: 登陆失败！', e)
        sys.exit(1)


class SendEmail:
    def __init__(self, mailsubject, mailtext, mailmsg_type, mailattach_path):
        self.subject = mailsubject
        self.text = mailtext
        self.msg_type = mailmsg_type
        self.attach_path = mailattach_path

    def send(self):
        if separate_delivery:
            print('开始分别发送邮件：')
            all_receivers = set()
            all_receivers.update(receivers)
            all_receivers.update(cc_receivers)
            all_receivers.update(bcc_receivers)
            for receiver in all_receivers:
                self.single_send(receiver)
        else:
            print('开始发送邮件：')
            self.batch_send()

    def single_send(self, receiver):
        try:
            server = connection()
            if not self.attach_path or self.attach_path.isspace():
                message = util.text(sender, [receiver], [], self.subject, self.text, self.msg_type)
            else:
                message = util.enclosure(sender, [receiver], [], self.subject, self.text, self.msg_type, self.attach_path)
            server.sendmail(sender, [receiver], message.as_string())
            server.quit()
            print('success: 已发送到', receiver, '的邮箱中！')
        except Exception as e:
            print('error: 发送邮件到', receiver, '失败！', e)

    def batch_send(self):
        server = connection()
        print('connection success')
        all_receivers = set()
        all_receivers.update(receivers)
        all_receivers.update(cc_receivers)
        if len(all_receivers) == 0:
            return
        if not self.attach_path or self.attach_path.isspace():
            message = util.text(sender, receivers, cc_receivers, self.subject, self.text, self.msg_type)
        else:
            message = util.enclosure(sender, receivers, cc_receivers, self.subject, self.text, self.msg_type, self.attach_path)
        try:
            res = server.sendmail(sender, all_receivers, message.as_string())
            server.quit()
        except Exception as e:
            res = {receiver: e for receiver in all_receivers}

        failed_receivers = set(res.keys())
        success_receivers = all_receivers - failed_receivers
        # 打印日志
        self.batch_send_log(success_receivers, failed_receivers, res)
        self.cc_send(success_receivers, failed_receivers, res)
        self.bcc_send(success_receivers, failed_receivers, res)

    def batch_send_log(self, success_receivers, failed_receivers, res):
        if len(receivers) == 0:
            return
        for receiver in receivers:
            # 判断发送成功或失败
            if receiver in success_receivers:
                print('success: 已发送到', receiver, '的邮箱中！')
                continue
            elif receiver in failed_receivers:
                print('error: 发送邮件到', receiver, '失败！', res.get(receiver))
                continue

    def cc_send(self, success_receivers, failed_receivers, res):
        if len(cc_receivers) == 0:
            return
        print('开始抄送邮件:')
        for receiver in cc_receivers:
            # 判断发送成功或失败
            if receiver in success_receivers:
                print('success: 已发送到', receiver, '的邮箱中！')
                continue
            elif receiver in failed_receivers:
                print('error: 发送邮件到', receiver, '失败！', res.get(receiver))
                continue

    def bcc_send(self, success_receivers, failed_receivers, res):
        if len(bcc_receivers) == 0:
            return
        print('开始密送邮件:')
        for receiver in bcc_receivers:
            # 判断发送成功或失败
            if receiver in success_receivers:
                print('success: 已发送到', receiver, '的邮箱中！')
                continue
            elif receiver in failed_receivers:
                print('error: 发送邮件到', receiver, '失败！', res.get(receiver))
                continue
            try:
                server = connection()
                if not self.attach_path or self.attach_path.isspace():
                    message = util.text(sender, receivers, cc_receivers, self.subject, self.text, self.msg_type)
                else:
                    message = util.enclosure(sender, receivers, cc_receivers, self.subject, self.text, self.msg_type,
                                                   self.attach_path)
                server.sendmail(sender, [receiver], message.as_string())
                server.quit()
                print('success: 已发送到', receiver, '的邮箱中！')
            except Exception as e:
                print('error: 发送邮件到', receiver, '失败！', e)
